<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>取消期约</title>
  </head>
  <body>
    <button id="start">开始</button>
    <button id="cancel">取消</button>
    <script>
      class CancelToken {
        constructor(cancelFn) {
          this.promise = new Promise((resolve, reject) => {
            cancelFn(() => {
              setTimeout(console.log, 0, "延迟取消");
              resolve();
            });
          });
        }
      }

      const startButton = document.querySelector("#start");
      const cancelButton = document.querySelector("#cancel");

      function cancelResolve(delay) {
        setTimeout(console.log, 0, "设置延迟时间");

        return new Promise((resolve, reject) => {
          const id = setTimeout(() => {
            setTimeout(console.log, 0, "延迟解决");
            resolve();
          }, delay);

          const cancelToken = new CancelToken(cancelCallback =>
            cancelButton.addEventListener("click", cancelCallback)
          );

          cancelToken.promise.then(() => clearTimeout(id));
        });
      }

      startButton.addEventListener("click", () => cancelResolve(1000));
    </script>
  </body>
</html>
